#pragma once

#include <linux/hrtimer.h>
#include <linux/tick.h>
#include <linux/workqueue.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/math.h>
#include <linux/minmax.h>

struct timer_events
{
	u64	local;
	u64	global;
};

enum tick_device_mode
{
    TICKDEV_MODE_PERIODIC,
    TICKDEV_MODE_ONESHOT,
};

struct tick_device
{
    struct clock_event_device *evtdev;
    enum tick_device_mode mode;
};

void tick_check_new_device(struct clock_event_device *newdev);
extern void tick_handle_periodic(struct clock_event_device *dev);
extern int tick_program_event(ktime_t expires, int force);
extern int tick_switch_to_oneshot(void (*handler)(struct clock_event_device *));
void tick_setup_periodic(struct clock_event_device *dev, int broadcast);

extern struct clock_event_device *this_clock_event(void);

extern void clockevents_switch_state(struct clock_event_device *dev,
                                     enum clock_event_state state);
extern int clockevents_program_event(struct clock_event_device *dev,
                                     ktime_t expires, bool force);
static inline enum clock_event_state clockevent_get_state(struct clock_event_device *dev)
{
    return dev->state_use_accessors;
}

static inline void clockevent_set_state(struct clock_event_device *dev,
					enum clock_event_state state)
{
    dev->state_use_accessors = state;
}

extern u64 get_next_timer_interrupt(unsigned long basej, u64 basem);

void tick_setup_sched_timer(bool hrtimer);

bool tick_is_oneshot_available(void);

bool tick_check_oneshot_change(int allow_nohz);

int __tick_do_timer_cpu(void);
